/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.kotlin.components

import kotlin.Boolean
import kotlin.Int
import kotlin.String
import kotlin.Unit
import org.apache.camel.kotlin.CamelDslMarker
import org.apache.camel.kotlin.UriDsl

/**
 * To call Kamelets
 */
public fun UriDsl.kamelet(i: KameletUriDsl.() -> Unit) {
  KameletUriDsl(this).apply(i)
}

@CamelDslMarker
public class KameletUriDsl(
  it: UriDsl,
) {
  private val it: UriDsl

  init {
    this.it = it
    this.it.component("kamelet")
  }

  private var templateId: String = ""

  private var routeId: String = ""

  /**
   * The Route Template ID
   */
  public fun templateId(templateId: String) {
    this.templateId = templateId
    it.url("$templateId/$routeId")
  }

  /**
   * The Route ID. Default value notice: The ID will be auto-generated if not provided
   */
  public fun routeId(routeId: String) {
    this.routeId = routeId
    it.url("$templateId/$routeId")
  }

  /**
   * Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions
   * (if possible) occurred while the Camel consumer is trying to pickup incoming messages, or the
   * likes, will now be processed as a message and handled by the routing Error Handler. Important:
   * This is only possible if the 3rd party component allows Camel to be alerted if an exception was
   * thrown. Some components handle this internally only, and therefore bridgeErrorHandler is not
   * possible. In other situations we may improve the Camel component to hook into the 3rd party
   * component and make this possible for future releases. By default the consumer will use the
   * org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or
   * ERROR level and ignored.
   */
  public fun bridgeErrorHandler(bridgeErrorHandler: String) {
    it.property("bridgeErrorHandler", bridgeErrorHandler)
  }

  /**
   * Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions
   * (if possible) occurred while the Camel consumer is trying to pickup incoming messages, or the
   * likes, will now be processed as a message and handled by the routing Error Handler. Important:
   * This is only possible if the 3rd party component allows Camel to be alerted if an exception was
   * thrown. Some components handle this internally only, and therefore bridgeErrorHandler is not
   * possible. In other situations we may improve the Camel component to hook into the 3rd party
   * component and make this possible for future releases. By default the consumer will use the
   * org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or
   * ERROR level and ignored.
   */
  public fun bridgeErrorHandler(bridgeErrorHandler: Boolean) {
    it.property("bridgeErrorHandler", bridgeErrorHandler.toString())
  }

  /**
   * To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is
   * enabled then this option is not in use. By default the consumer will deal with exceptions, that
   * will be logged at WARN or ERROR level and ignored.
   */
  public fun exceptionHandler(exceptionHandler: String) {
    it.property("exceptionHandler", exceptionHandler)
  }

  /**
   * Sets the exchange pattern when the consumer creates an exchange.
   */
  public fun exchangePattern(exchangePattern: String) {
    it.property("exchangePattern", exchangePattern)
  }

  /**
   * If sending a message to a direct endpoint which has no active consumer, then we can tell the
   * producer to block and wait for the consumer to become active.
   */
  public fun block(block: String) {
    it.property("block", block)
  }

  /**
   * If sending a message to a direct endpoint which has no active consumer, then we can tell the
   * producer to block and wait for the consumer to become active.
   */
  public fun block(block: Boolean) {
    it.property("block", block.toString())
  }

  /**
   * Whether the producer should fail by throwing an exception, when sending to a kamelet endpoint
   * with no active consumers.
   */
  public fun failIfNoConsumers(failIfNoConsumers: String) {
    it.property("failIfNoConsumers", failIfNoConsumers)
  }

  /**
   * Whether the producer should fail by throwing an exception, when sending to a kamelet endpoint
   * with no active consumers.
   */
  public fun failIfNoConsumers(failIfNoConsumers: Boolean) {
    it.property("failIfNoConsumers", failIfNoConsumers.toString())
  }

  /**
   * Whether the producer should be started lazy (on the first message). By starting lazy you can
   * use this to allow CamelContext and routes to startup in situations where a producer may otherwise
   * fail during starting and cause the route to fail being started. By deferring this startup to be
   * lazy then the startup failure can be handled during routing messages via Camel's routing error
   * handlers. Beware that when the first message is processed then creating and starting the producer
   * may take a little time and prolong the total processing time of the processing.
   */
  public fun lazyStartProducer(lazyStartProducer: String) {
    it.property("lazyStartProducer", lazyStartProducer)
  }

  /**
   * Whether the producer should be started lazy (on the first message). By starting lazy you can
   * use this to allow CamelContext and routes to startup in situations where a producer may otherwise
   * fail during starting and cause the route to fail being started. By deferring this startup to be
   * lazy then the startup failure can be handled during routing messages via Camel's routing error
   * handlers. Beware that when the first message is processed then creating and starting the producer
   * may take a little time and prolong the total processing time of the processing.
   */
  public fun lazyStartProducer(lazyStartProducer: Boolean) {
    it.property("lazyStartProducer", lazyStartProducer.toString())
  }

  /**
   * The timeout value to use if block is enabled.
   */
  public fun timeout(timeout: String) {
    it.property("timeout", timeout)
  }

  /**
   * The timeout value to use if block is enabled.
   */
  public fun timeout(timeout: Int) {
    it.property("timeout", timeout.toString())
  }

  /**
   * Location of the Kamelet to use which can be specified as a resource from file system, classpath
   * etc. The location cannot use wildcards, and must refer to a file including extension, for example
   * file:/etc/foo-kamelet.xml
   */
  public fun location(location: String) {
    it.property("location", location)
  }

  /**
   * Kamelets, by default, will not do fine-grained error handling, but works in no-error-handler
   * mode. This can be turned off, to use old behaviour in earlier versions of Camel.
   */
  public fun noErrorHandler(noErrorHandler: String) {
    it.property("noErrorHandler", noErrorHandler)
  }

  /**
   * Kamelets, by default, will not do fine-grained error handling, but works in no-error-handler
   * mode. This can be turned off, to use old behaviour in earlier versions of Camel.
   */
  public fun noErrorHandler(noErrorHandler: Boolean) {
    it.property("noErrorHandler", noErrorHandler.toString())
  }
}
